package com.yunjian.admin.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Date;
import java.util.UUID;

import org.apache.shiro.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.yunjian.admin.vo.WebResult;
import com.yunjian.core.basic.model.UserFile;
import com.yunjian.core.basic.service.CacheService;
import com.yunjian.core.basic.service.SResourceService;
import com.yunjian.core.basic.service.SUserService;
import com.yunjian.core.basic.service.UserFileService;
import com.yunjian.util.ArrayUtil;
import com.yunjian.util.StringUtil;

/**
 * 公共访问类（无需登录）
 * 
 * @author sonta
 */
@Api(description="公共访问模块（无需登录）")
@RequestMapping("/public")
@Controller
public class PublicController {
	
	private final static Logger logger = LoggerFactory.getLogger(PublicController.class);
	
	@Autowired
	private CacheService cacheService;
	@Autowired
	private SResourceService sResourceService;
	@Autowired
	private SUserService sUserService;
	@Autowired
	private UserFileService userFileService;
	
	@Value("${system.user-file-syspath}")
	private String userFileSysPath;
	
	@ApiOperation(value="用户登录状态反馈")
	@RequestMapping(value = "/loginStatus", method = {RequestMethod.GET})
	@ResponseBody
	public WebResult<String> loginStatus() {
		WebResult<String> ret = new WebResult<String>();
		if(SecurityUtils.getSubject().isAuthenticated()){
			return ret.setCoder(WebResult.Coder.SUCCESS);
		}
		return ret.setCoder(WebResult.Coder.C9000);
	}
	
	@ApiOperation(value="返回码（code,msg）定义")
	@RequestMapping(value="/getCoders", method = {RequestMethod.GET, RequestMethod.POST})
	@ResponseBody
	public String getCoders(){
		logger.info("获取返回码定义");
		return WebResult.Coder.getCoderStr();
	}
	
	@ApiOperation(value="文件上传业务类别码及其相关限制获取")
	@RequestMapping(value="/getFileUploadBusiType", method = {RequestMethod.GET, RequestMethod.POST})
	@ResponseBody
	public String getFileUploadBusiType(){
		logger.info("获取返回码定义");
		return UserFile.BusiType.getBusiTypeStr();
	}
	
	/**
	 * 图片预览（流）
	 * @param id 文件编号
	 * @return
	 */
	@ApiOperation(value="获取图片")
	@RequestMapping(value = "/previewImg", method = {RequestMethod.GET})
	public ResponseEntity<?> previewPubImg(
			@ApiParam(value="图片文件编号")@RequestParam(required=true) String id
			) {
		UserFile dbFile = userFileService.selectByPrimaryKey(id);
		if (dbFile == null) {
			return new ResponseEntity<String>("文件不存在", HttpStatus.NOT_FOUND);
		}
		String[] imgExts = new String[]{"jpg", "png", "gif"};
		if (!ArrayUtil.contains(imgExts, dbFile.getFileExt())) {
			return new ResponseEntity<String>("非图片文件", HttpStatus.BAD_GATEWAY);
		}
		File file = new File(StringUtil.isEmpty(dbFile.getSysSavePath()) ? dbFile.getBusiSavePath() : dbFile.getSysSavePath() + dbFile.getBusiSavePath());
		if (!file.exists()) {
			logger.error("db file not exist - {}", dbFile.getId());
			return new ResponseEntity<String>("文件不存在", HttpStatus.NOT_FOUND);
		}
		FileInputStream fis = null;
		ByteArrayOutputStream bos = new ByteArrayOutputStream(1000);
		try {
			fis= new FileInputStream(file);
			byte[] b = new byte[1000];
			int n;
			while ((n = fis.read(b)) != -1) {
				bos.write(b, 0, n);
			}
			fis.close();
			bos.close();
			byte[] fileByte = bos.toByteArray();
			HttpHeaders headers = new HttpHeaders();
			String dfileName = new String(dbFile.getFileOrignName().getBytes("gb2312"),"iso8859-1");
			headers.setContentDispositionFormData("attachment", dfileName);
			return new ResponseEntity<byte[]>(fileByte, headers, HttpStatus.OK);
		} catch (Exception e) {
			logger.error("文件下载错误", e);
		} finally {
			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					logger.error("文件下载错误", e);
				}
			}
		}
		return new ResponseEntity<String>("错误", HttpStatus.INTERNAL_SERVER_ERROR);
	}
	
	/**
	 * 上传房间照片
	 * @param id
	 * @return
	 */
	@ApiOperation(value="用户文件上传")
	@RequestMapping(value = "/uploadFiles", method = {RequestMethod.POST})
	@ResponseBody
	public WebResult<String> uploadHousePhoto(
			@ApiParam(value="用户编号")@RequestParam(required=true) String userId,
			@ApiParam(value="业务类别码 请通过公共接口'/getFileUploadBusiType'获取")@RequestParam(required=true) String busiType,
			@ApiParam(value="文件")@RequestParam(required=true) MultipartFile uploadFile
			) {
		WebResult<String> ret = new WebResult<>();
		logger.info("用户[{}]上传文件：{}", userId, uploadFile.getOriginalFilename());
		UserFile.BusiType type = UserFile.BusiType.getTypeByCode(busiType);
		if (type == null) {
			logger.error("{}-{}", ret.getMsg(), "业务代码不存在");
			return ret;
		}
		String fileName = uploadFile.getOriginalFilename();
		String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
		// 文件格式校验
		if (!ArrayUtil.contains(type.getAllowExts(), fileExt)) { 
			logger.warn("{}-{}", ret.getMsg(), "格式非法");
			return ret;
		}
		// 文件大小校验
		if (uploadFile.getSize() > type.getAllowSize()) {
			logger.warn("{}-{}", ret.getMsg(), "大小非法");
			return ret;
		}
		String fileId = UUID.randomUUID().toString();
		// 文件保存相对路径->存库
		String relativePathName = userId + File.separator + type.getCode() + File.separator + fileExt + File.pathSeparator + fileId + "." + fileExt;
		if (!userFileSysPath.endsWith("/") && !userFileSysPath.endsWith("\\")) {
			userFileSysPath += File.separator;
		}
		// 文件保存绝对路径
		String toSavePathName = userFileSysPath + relativePathName;
		logger.debug("保存绝对路径：{}", toSavePathName);
		File saveFile = new File(toSavePathName);
		if (!saveFile.getParentFile().exists()) {
			saveFile.getParentFile().mkdirs();
		}
		try {
			uploadFile.transferTo(saveFile);
		} catch (IllegalStateException | IOException e) {
			ret.setCoder(WebResult.Coder.ERROR);
			logger.error(ret.getMsg(), e);
			return ret;
		}
		
		// 文件数据入库
		UserFile dbFile = new UserFile();
		dbFile.setId(fileId); // 文件编号
		dbFile.setFileOrignName(fileName); // 文件名
		dbFile.setFileExt(fileExt); // 文件后缀
		dbFile.setFileSize(uploadFile.getSize()); // 文件大小
		dbFile.setSysSavePath(userFileSysPath); // 系统保存路径
		dbFile.setBusiSavePath(relativePathName); // 业务保存路径
		dbFile.setCreateUserId(userId); // 上传者 // TODO 暂时不验证是否存在 
		dbFile.setSysNo("01"); // 系统编号
		dbFile.setFileStatus(2); // 文件状态:待使用
		dbFile.setBusiType(type.getCode()); // 业务类型
		dbFile.setCreateTime(new Date());
		int it = userFileService.insert(dbFile);
		if (it != 1) {
			ret.setCoder(WebResult.Coder.C2001);
			logger.error(ret.getMsg());
			return ret;
		}
		
		ret.setAttach(fileId);
		return ret.setCoder(WebResult.Coder.SUCCESS);
	}
	
	
	
}
